﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using YaP.Forms.Abstract;
using YaP.Library.Extensions;
using YaP.Library.YapControls;

namespace YaP.Forms
{
    public partial class EditorForm : YaPForm
    {
        private const string UnsaveText = "*";
        private int CurrentIndex;
        private List<Library.AliasFileDesc> filelistField;
        private string filepathField;

        public EditorForm(List<Library.AliasFileDesc> list)
        {
            InitializeComponent();
            FileList = list;
            CurrentIndex = 0;
            if (filelistField.Count == 0)
            {
                Library.AliasFileDesc newdesc = new YaP.Library.AliasFileDesc();
                FileList.Add(newdesc);

                LabelFile.Text = "New*";
                labelImgValid.Image = Properties.Resources.stop;
            }
            else
            {
                LabelFile.Text = CurrentFile.FilePath;
                if (CurrentFile.Active)
                {
                    labelImgValid.Image = Properties.Resources.valid;
                }
                else
                    labelImgValid.Image = Properties.Resources.stop;
                ReadFromFile(CurrentFile.FilePath);
            }

            RegenViewMenu();
        }

        internal List<Library.AliasFileDesc> FileList
        {
            get { return filelistField; }
            set
            {
                filelistField = value;
                RegenViewMenu();
                //regen "View" menu
            }
        }

        private Library.AliasFileDesc CurrentFile
        {
            get { return filelistField[CurrentIndex]; }
        }

        private string CurrentFilePath
        {
            get { return filepathField; }
            set
            {
                filepathField = value;
                LabelFile.Text
                    = filepathField;
                RegenViewMenu();
            }
        }

        private void SaveFile()
        {
            TextFile txtf = new TextFile(CurrentFile.FilePath);
            if (txtf.Open())
            {
                txtf.OverWrite(richEditor.Text);
                txtf.Close();
                LabelFile.Text.TrimEnd(UnsaveText.ToCharArray());
            }
            else
            {
                MessageBox.Show("Cannot open file or create. Please choose an other destination", "Error!",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                CurrentFile.FilePath = string.Empty;
                DoSaveProcess(true, false);
            }
        }

        private bool DoSaveProcess(bool AskPath, bool AskConfirmation)
        {
            if ((richEditor.Text != string.Empty) && (!richEditor.Text.ContainsOnlySpaces()))
            {
                if (AskConfirmation)
                {
                    DialogResult dr = MessageBox.Show(@"Do you want the save current script ?", "Save?",
                                                      MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    if (dr == DialogResult.Yes)
                    {
                        goto DoIt;
                    }
                    return false;
                }

                //Revenge of the goto ! :D
            DoIt:
                if ((CurrentFile.FilePath != string.Empty) && (!AskPath))
                {
                    SaveFile();
                    return true;
                }
                SaveFileDialog sd = new SaveFileDialog();
                sd.Filter = @"Ini file (*.ini) | *.ini|Text File (*.txt) | *.txt";
                DialogResult savedr = sd.ShowDialog();
                if (savedr == DialogResult.OK)
                {
                    CurrentFile.FilePath = sd.FileName;
                    SaveFile();
                    return true;
                }
                return false;
            }
            return false;
        }

        private void RegenViewMenu()
        {
            viewToolStripMenuItem.DropDownItems.Clear();
            foreach (Library.AliasFileDesc adesc in FileList)
            {
                ToolStripScriptItem toadd = new ToolStripScriptItem();
                string[] split = adesc.FilePath.Split(@"\".ToCharArray());
                string FileName = split[split.Length - 1];
                if (FileName != string.Empty)
                {
                    toadd.FullPath = adesc.FilePath;
                    toadd.Text = FileName;
                    toadd.Click += ViewMenuItem_Click;
                    viewToolStripMenuItem.DropDownItems.Add(toadd);
                }
            }
        }

        private void ViewMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripScriptItem ts = sender as ToolStripScriptItem;
            CurrentIndex = FileList.IndexOf((from lst in FileList
                                             where lst.FilePath == ts.FullPath
                                             select lst).Single());
            TextFile txtf = new TextFile(ts.FullPath);
            txtf.Open();
            richEditor.Text = txtf.ReadAll(FileOperationMode.Synchronous);
            txtf.Close();
        }

        private async Task ReadFromFile(string path)
        {
            richEditor.Text = File.ReadAllText(path);

        }

        private void loadFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Thread TLoader = new Thread(() =>
                                            {
                                                DialogResult dr = openAliasDialog.ShowDialog();
                                                if (dr == DialogResult.OK)
                                                {
                                                    int nbdesc = (from lst in FileList
                                                                  where lst.FilePath == openAliasDialog.FileName
                                                                  select lst).ToList().Count;
                                                    if (nbdesc == 0)
                                                    {
                                                        ReadFromFile(openAliasDialog.FileName);
                                                        var desc = new YaP.Library.AliasFileDesc(openAliasDialog.FileName, false);
                                                        FileList.Add(desc);
                                                        CurrentIndex = FileList.IndexOf(desc);
                                                        RegenViewMenu();
                                                        LabelFile.Text = openAliasDialog.FileName;
                                                    }
                                                }
                                            });

            TLoader.SetApartmentState(ApartmentState.STA);
            TLoader.Start();


        }

        private void openAliasDialog_FileOk(object sender, CancelEventArgs e)
        {
        }


        private void EditorForm_Load(object sender, EventArgs e)
        {
            lstWindow.SelectedIndex = 1;
        }

        private void checkSyntaxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Library.mircLib.AliasParser prs = new YaP.Library.mircLib.AliasParser();
                prs.SetText(richEditor.Text);
                SerializableDictionary<string, Library.AliasDesc> dic = prs.Dictionnary;
                if (dic != null)
                {
                    MessageBox.Show("Syntax OK.", "Syntax Checker", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Library.mircLib.SyntaxEception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void tsButtonNew_Click(object sender, EventArgs e)
        {
            if (!DoSaveProcess(false, true))
            {
                FileList.Remove(FileList[CurrentIndex]);
            }
            var toadd = new YaP.Library.AliasFileDesc();
            FileList.Add(toadd);
            CurrentIndex = FileList.IndexOf(toadd);
            LabelFile.Text = "New*";
            labelImgValid.Image = Properties.Resources.stop;
            richEditor.Text = string.Empty;
        }


        private void toolStripStatusLabel1_Click(object sender, EventArgs e)
        {
            CurrentFile.Active = !CurrentFile.Active;
            if (CurrentFile.Active)
            {
                labelImgValid.Image = Properties.Resources.valid;
            }
            else
                labelImgValid.Image = Properties.Resources.stop;
        }

        private void tsButtonSave_Click(object sender, EventArgs e)
        {
            DoSaveProcess(false, false);
        }

        private void richEditor_TextChanged(object sender, EventArgs e)
        {
            if (!LabelFile.Text.EndsWith(UnsaveText))
                LabelFile.Text += UnsaveText;
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DoSaveProcess(true, false);
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(richEditor.SelectedText);
        }

        private void cutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                Clipboard.SetText(richEditor.SelectedText);
            }
            catch (Exception)
            {
            }
            richEditor.SelectedText = string.Empty;
        }

        private void EditorForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            var emptymembers = (from lst in FileList
                                where ((lst.FilePath == string.Empty) || (lst.FilePath.ContainsOnlySpaces()))
                                select lst).ToList();
            foreach (Library.AliasFileDesc desc in emptymembers)
            {
                FileList.Remove(desc);
            }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            FileList.Remove(CurrentFile);
            Close();
        }

        private void tabEditor_SelectedIndexChanged(object sender, EventArgs e)
        {
            string TabName = tabEditor.SelectedTab.Name;
            switch (TabName)
            {
                case "tabAliases":
                    viewToolStripMenuItem.Visible = true;
                    statusStrip1.Visible = true;
                    break;
                case "tabThemes":
                    viewToolStripMenuItem.Visible = false;
                    statusStrip1.Visible = false;
                    break;
            }

        }

        private void lstWindow_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (groupRegion.HasChildren)
            {
                groupRegion.Controls.Clear();
            }
            if (groupSettings.HasChildren)
            {
                groupSettings.Controls.Clear();
            }

            switch (lstWindow.SelectedItem.ToString())
            {
                case "Main":
                    MainPreviewer mprv = new MainPreviewer();
                    mprv.Parent = groupRegion;
                    mprv.Dock = DockStyle.Fill;
                    mprv.OnBackMdiClicked += mprv_OnBackMdiClicked;
                    mprv.OnSideBarClicked += mprv_OnSideBarClicked;
                    mprv.OnStatusClicked += mprv_OnStatusClicked;
                    break;

            }
        }

        void mprv_OnStatusClicked(object sender, EventArgs e)
        {

        }

        void mprv_OnSideBarClicked(object sender, EventArgs e)
        {

        }

        void mprv_OnBackMdiClicked(object sender, EventArgs e)
        {
            if (groupSettings.HasChildren)
            {
                groupSettings.Controls.Clear();
            }
            MainFormConfigurator mfc = new MainFormConfigurator();
            mfc.Parent = groupSettings;
            mfc.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            mfc.OnImgChanged += new MainFormConfigurator.BackImgChanged(mfc_OnImgChanged);
            mfc.OnImgModeChanged += new MainFormConfigurator.ImgModeChanged(mfc_OnImgModeChanged);
            mfc.OnMainBackColorChanged += new MainFormConfigurator.MainBackColorChanged(mfc_OnMainBackColorChanged);
        }

        void mfc_OnMainBackColorChanged(object sender, System.Drawing.Color c)
        {
            if (OnMainBackColorChanged != null)
                OnMainBackColorChanged(this, c);
        }

        void mfc_OnImgModeChanged(object sender, ImageLayout layout)
        {
            if (OnMainImgModeChanged != null)
                OnMainImgModeChanged(this, layout);
        }

        void mfc_OnImgChanged(object sender, string FilePath)
        {
            if (OnMainBackImageChanged != null)
            {
                OnMainBackImageChanged(this, FilePath);
            }
        }

        public event MainFormConfigurator.BackImgChanged OnMainBackImageChanged;
        public event MainFormConfigurator.ImgModeChanged OnMainImgModeChanged;
        public event MainFormConfigurator.MainBackColorChanged OnMainBackColorChanged;
    }
}